package com.carl.lambda.simpleLambda.lambda2;


import org.junit.Test;

import java.util.Comparator;
import java.util.function.Consumer;

/*
 * 一、Lambda 表达式的基础语法：Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符
 * 						    箭头操作符将 Lambda 表达式拆分成两部分：
 *
 * 左侧：Lambda 表达式的参数列表
 * 右侧：Lambda 表达式中所需执行的功能， 即 Lambda 体
 *
 * 语法格式一：无参数，无返回值
 * 		() -> System.out.println("Hello Lambda!");
 *
 * 语法格式二：有一个参数，并且无返回值
 * 		(x) -> System.out.println(x)
 *
 * 语法格式三：若只有一个参数，小括号可以省略不写
 * 		x -> System.out.println(x)
 *
 * 语法格式四：有两个以上的参数，有返回值，并且 Lambda 体中有多条语句
 *		Comparator<Integer> com = (x, y) -> {
 *			System.out.println("函数式接口");
 *			return Integer.compare(x, y);
 *		};
 *
 * 语法格式五：若 Lambda 体中只有一条语句， return 和 大括号都可以省略不写
 * 		Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
 *
 * 语法格式六：Lambda 表达式的参数列表的数据类型可以省略不写，因为JVM编译器通过上下文推断出，数据类型，即“类型推断”
 * 		(Integer x, Integer y) -> Integer.compare(x, y);
 *
 * 上联：左右遇一括号省
 * 下联：左侧推断类型省
 * 横批：能省则省
 *
 * 二、Lambda 表达式需要“函数式接口”的支持
 * 函数式接口：接口中只有一个抽象方法的接口，称为函数式接口。 可以使用注解 @FunctionalInterface 修饰
 * 			 可以检查是否是函数式接口
 */
public class LambdaTest {

    //语法格式一：无参数，无返回值
    @Test
    public void test(){

        //局部内部类中应用了局部变量,jdk 1.7 前，必须是 final
        int num = 0;
        //匿名内部类
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world"+num);
            }
        };
        r.run();

        //lambda
        Runnable runnable = () -> System.out.println("hello world"+num);
        runnable.run();
    }

    //语法格式二：有一个参数，并且无返回值
    @Test
    public void test01(){
        Consumer<String> consumer = System.out::println; //等同于(x) -> System.out.println(x);
        consumer.accept("lambda真的简单");
    }

    //语法格式三：若只有一个参数，小括号可以省略不写
    @Test
    public void test03(){
        Consumer<String> consumer = x -> System.out.println(x);
        consumer.accept("lambda真的简单");
    }

    //语法格式四：有两个以上的参数，有返回值，并且 Lambda 体中有多条语句
    @Test
    public void test04(){
        Comparator<Integer> com = (x,y) ->{
            System.out.println("比较两个数大小");
            return Integer.compare(x,y);
        };
        int compare = com.compare(1, 2);
        System.out.println(compare);

    }
    //语法格式五：若 Lambda 体中只有一条语句， return 和 大括号都可以省略不写
    @Test
    public void test05(){
        Comparator<Integer> com = Integer::compare; // 等同于(x,y) -> Integer.compare(x,y);
        System.out.println(com.compare(1, 2));
    }
    //语法格式六：Lambda 表达式的参数列表的数据类型可以省略不写，因为JVM编译器通过上下文推断出，数据类型，即“类型推断”
    @Test
    public void test06(){
        Comparator<Integer> com = (Integer x,Integer y) -> Integer.compare(x,y);//这么写也是没毛病的
        System.out.println(com.compare(1, 2));
    }




}
